/*
 * @Author: 0x9DEFA478
 * @Date: 2025-08-01 23:33:39
 * @LastEditTime: 2025-10-08 22:20:44
 * @LastEditors: 0x9DEFA478
 * @Description: 
 * 
 */
#ifndef hHMakeTargetTask_Abstract_HPP_
#define hHMakeTargetTask_Abstract_HPP_
#include <functional>
#include <iostream>
#include <utility>
#include "HMakeDependencyChain.hpp"
#include "HMakeTargetConfig.hpp"


namespace HMake{

  class TargetTask{
    public:
      using Pointer=H::PointerShare<TargetTask>;
      using ConstPointer=Pointer::Const;

      enum class AttributeMask:uint32_t{
        None=0,
        IsPrintArg=1U<<0,
        IsPrintSkip=1U<<1,
      };

      friend constexpr AttributeMask operator&(AttributeMask a,AttributeMask b)noexcept{
        return AttributeMask(static_cast<uint32_t>(a)&static_cast<uint32_t>(b));
      }
      friend constexpr AttributeMask operator|(AttributeMask a,AttributeMask b)noexcept{
        return AttributeMask(static_cast<uint32_t>(a)|static_cast<uint32_t>(b));
      }
      friend AttributeMask& operator|=(AttributeMask& a,AttributeMask b)noexcept{return a=a|b;}
      friend constexpr bool operator!=(AttributeMask a,uint32_t b)noexcept{return static_cast<uint32_t>(a)!=b;}
      friend constexpr bool operator!=(uint32_t a,AttributeMask b)noexcept{return b!=a;}
      friend constexpr bool operator==(AttributeMask a,uint32_t b)noexcept{return static_cast<uint32_t>(a)==b;}
      friend constexpr bool operator==(uint32_t a,AttributeMask b)noexcept{return b==a;}

    public:
      TargetTask(const HMake::TargetConfig::ConstPointer& targetConfig,const std::string& shell,AttributeMask attribute);
      virtual ~TargetTask()=default;

      virtual DependencyChain::Item::Pointer MakeTask()=0;

      std::string Name()const noexcept{return targetConfig->Name();}

      int PreBuild();

    protected:
      void DisablePreBuild();

      void SetLogTag(std::string& RunLog,const std::string& RunLog_Initial,std::string& SkipLog,const std::string& SkipLog_Initial,const std::list<std::string> Args);
      void SetLogTag(std::string& RunLog,const std::string& RunLog_Initial,std::string& SkipLog,const std::string& SkipLog_Initial,const std::list<std::list<std::string>> ArgsList);


    private:
      int RunPreProcess(const Value& arg);

    protected:
      const HMake::TargetConfig::ConstPointer targetConfig;
      const AttributeMask attribute;
      std::list<Value> postbuild;
    private:
      std::list<Value> prebuild;

    public:
      static std::string StringListToString(const std::list<std::string>& list);
      static std::string ReadValue(const TargetConfig::ConstPointer& targetConfig,const std::string& ValueName);
      static std::string ReadValue_WithDefault(const TargetConfig::ConstPointer& targetConfig,const std::string& ValueName,const std::string& DefaultValue="");
      static std::string ReadValue_WithPathDefault(const TargetConfig::ConstPointer& targetConfig,const std::string& ValueName,const H::Path& Path,const std::string& cwd,const std::string& DefaultValue="");
      static std::list<std::string> ReadValueArray(const TargetConfig::ConstPointer& targetConfig,const std::string& ValueName);
      static std::list<std::string> ReadChildAllValue_WithPath(const TargetConfig::ConstPointer& targetConfig,const std::string& ValueName,const H::Path& Path,const std::string& cwd);
      static std::list<Value> ReadCommand(const TargetConfig::ConstPointer& targetConfig,const std::string& ValueName,const std::string& shell);

  };

}


#endif //hHMakeTargetTask_Abstract_HPP_
